﻿using Mapster;
using Raffles.OA.Data;
using Raffles.OA.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

namespace Raffles.OA.WebApp.Areas.Manage.Controllers
{
    public class RoleController : BaseController<Role>
    {
        /// <summary>
        /// 获取角色分页列表
        /// </summary>
        /// <param name="param"></param>
        /// <param name="pagination"></param>
        /// <returns></returns>
        public ActionResult GetPageListJson(BaseSearchParam param, Pagination pagination)
        {
            int totalCount = 0;
            var roles = _dbContext.Queryable<Role>().Where(x => !x.DeletedMark)
                                                    .WhereIF(!param.KeyWord.IsEmpty(),x=>x.Name==param.KeyWord.Trim())
                                                    .OrderBy(x=>x.DisplayOrder)
                                                    .ToPageList(pagination.PageIndex, pagination.PageSize, ref totalCount);
            return Content(DataResult<List<Role>>.PageResult(roles, totalCount).ToJson());
        }

        public ActionResult Form(int? id)
        {
            Role role = new Role();
            if (id != null)
            {
                role = _dbContext.Queryable<Role>().InSingle(id);
            }
            return View(role);
        }

        /// <summary>
        /// 角色保存
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult SaveForm(RoleDto roleDto)
        {
            try
            {
                if (roleDto.Id == null)
                {
                    if (_dbContext.Queryable<Role>().Any(x => !x.DeletedMark && x.Code == roleDto.Code))
                    {
                        return Json(DataResult.Error("角色编码不允许重复"));
                    }
                    Role role = new Role();
                    roleDto.Adapt(role);
                    role.CreatedBy = OperatorProvider.Provider.GetCurrent().Id;
                    _dbContext.Insertable<Role>(role).ExecuteCommand();
                    return Json(DataResult.Success("角色新增成功"));
                }
                else
                {
                    if (_dbContext.Queryable<Role>().Any(x => !x.DeletedMark && x.Code == roleDto.Code && x.Id != roleDto.Id))
                    {
                        return Json(DataResult.Error("角色编码不允许重复"));
                    }
                    Role role = _dbContext.Queryable<Role>().InSingle(roleDto.Id);
                    roleDto.Adapt(role);
                    role.UpdatedOn = DateTime.Now;
                    role.UpdatedBy = OperatorProvider.Provider.GetCurrent().Id;
                    _dbContext.Updateable<Role>(role).ExecuteCommand();
                    return Json(DataResult.Success("角色编辑成功"));
                }
            }
            catch (Exception ex)
            {
                return Json(DataResult.Error($"保存失败,失败原因:{ex.Message}"));
            }
        }

        /// <summary>
        /// 角色删除
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult DeleteData(int id)
        {
            if (_dbContext.Queryable<UserRole>().Any(x => x.RoleId == id))
            {
                return Json(DataResult.Error("该角色下已分配员工,不允许删除"));
            }
            Role role = _dbContext.Queryable<Role>().InSingle(id);
            role.DeletedMark = true;
            role.UpdatedOn = DateTime.Now;
            role.UpdatedBy = OperatorProvider.Provider.GetCurrent().Id;
            _dbContext.Updateable<Role>(role).ExecuteCommand();
            return Json(DataResult.Success("删除成功"));
        }

        /// <summary>
        /// 角色授权
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        public ActionResult Authorize(int roleId)
        {
            var roleMenus = _dbContext.Queryable<Role>().Includes(x => x.Menus).First(x => x.Id == roleId);
            return View(roleMenus);
        }

        /// <summary>
        /// 加载权限树
        /// </summary>
        /// <returns></returns>
        public ActionResult LoadMenuTree()
        {
            List<TreeVo> treeVos = _dbContext.Queryable<Menu>().Where(x => !x.DeletedMark && x.EnabledMark)
                                           .OrderBy(x => x.DisplayOrder)
                                           .Select(x => new TreeVo { id = x.Id, pId = x.ParentId, name = x.Name })
                                           .ToList();
            return Json(DataResult<List<TreeVo>>.Success(treeVos, "加载成功"), JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// 保存角色权限
        /// </summary>
        /// <param name="roleId"></param>
        /// <param name="menuIds"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult SaveMenus(int roleId, string menuIds)
        {
            try
            {
                _dbContext.Ado.BeginTran();
                var roleMenusOld = _dbContext.Queryable<RoleMenu>().Where(x => x.RoleId == roleId).ToList();
                _dbContext.Deleteable<RoleMenu>(roleMenusOld).ExecuteCommand();
                //保存现有权限
                List<int> menus = Array.ConvertAll<string, int>(menuIds.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries), s => s.StringToInt32()).Distinct().ToList();
                List<RoleMenu> roleMenusNew = new List<RoleMenu>();
                foreach (var menuId in menus)
                {
                    roleMenusNew.Add(new RoleMenu() { RoleId = roleId, MenuId = menuId });
                }
                _dbContext.Insertable<RoleMenu>(roleMenusNew).ExecuteCommand();
                _dbContext.Ado.CommitTran();
                return Json(DataResult.Success("权限分配成功"));
            }
            catch (Exception ex)
            {
                _dbContext.Ado.RollbackTran();
                return Json(DataResult.Error($"保存失败,失败原因:{ex.Message}"));
            }
        }

        /// <summary>
        /// 获取审批角色列表
        /// </summary>
        /// <param name="param"></param>
        /// <param name="pagination"></param>
        /// <returns></returns>
        public ActionResult GetAuditListJson(BaseSearchParam param)
        { 
            var roles = _dbContext.Queryable<Role>().Where(x => !x.DeletedMark)
                                                    .WhereIF(!param.KeyWord.IsEmpty(), x => x.Name == param.KeyWord.Trim())
                                                    .ToList();
            return Content(DataResult<List<Role>>.Success(roles).ToJson());
        }
    }
}